"""
Flask任务队列和后台作业示例 - 展示异步任务处理、定时任务等功能
包含Celery集成、任务监控、任务调度等特性
"""

from flask import Flask, request, jsonify, g
import os
import sys
import time
import json
from datetime import datetime, timedelta
from typing import Dict, Any, List, Optional
from enum import Enum
from dataclasses import dataclass, asdict
import threading
import queue
import schedule
from concurrent.futures import ThreadPoolExecutor, as_completed
import asyncio
from functools import wraps

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from python_backend_toolkit.auth import JWTAuth
from python_backend_toolkit.cache import CacheManager, MemoryCache
from python_backend_toolkit.database import Base, BaseModel, DatabaseSession
from python_backend_toolkit.logging import get_logger, setup_logging
from python_backend_toolkit.http_client import HTTPClient, AsyncHTTPClient
from python_backend_toolkit.utils import generate_uuid, format_datetime
from python_backend_toolkit.api.responses import (
    SuccessResponse, ErrorResponse, CreatedResponse
)
from python_backend_toolkit.api.exceptions import (
    ValidationError, NotFoundError
)

from sqlalchemy import Column, Integer, String, Text, DateTime, Boolean, Float, Enum as SQLEnum


# ========================================================================
# 数据模型和枚举
# ========================================================================

class TaskStatus(Enum):
    """任务状态"""
    PENDING = "pending"
    RUNNING = "running"
    SUCCESS = "success"
    FAILED = "failed"
    RETRY = "retry"
    CANCELLED = "cancelled"


class TaskPriority(Enum):
    """任务优先级"""
    LOW = "low"
    NORMAL = "normal"
    HIGH = "high"
    URGENT = "urgent"


@dataclass
class TaskResult:
    """任务结果"""
    task_id: str
    status: TaskStatus
    result: Any = None
    error: str = None
    started_at: datetime = None
    completed_at: datetime = None
    duration: float = None
    
    def to_dict(self):
        data = asdict(self)
        if self.started_at:
            data['started_at'] = self.started_at.isoformat()
        if self.completed_at:
            data['completed_at'] = self.completed_at.isoformat()
        data['status'] = self.status.value
        return data


class Task(BaseModel):
    """任务模型"""
    __tablename__ = 'background_tasks'
    
    task_id = Column(String(50), unique=True, nullable=False)
    name = Column(String(200), nullable=False)
    function_name = Column(String(100), nullable=False)
    args = Column(Text)  # JSON格式的参数
    kwargs = Column(Text)  # JSON格式的关键字参数
    priority = Column(SQLEnum(TaskPriority), default=TaskPriority.NORMAL)
    status = Column(SQLEnum(TaskStatus), default=TaskStatus.PENDING)
    result = Column(Text)  # JSON格式的结果
    error_message = Column(Text)
    retry_count = Column(Integer, default=0)
    max_retries = Column(Integer, default=3)
    started_at = Column(DateTime)
    completed_at = Column(DateTime)
    scheduled_at = Column(DateTime)  # 计划执行时间


class ScheduledJob(BaseModel):
    """定时任务模型"""
    __tablename__ = 'scheduled_jobs'
    
    job_id = Column(String(50), unique=True, nullable=False)
    name = Column(String(200), nullable=False)
    function_name = Column(String(100), nullable=False)
    args = Column(Text)  # JSON格式的参数
    kwargs = Column(Text)  # JSON格式的关键字参数
    cron_expression = Column(String(100))  # Cron表达式
    interval_seconds = Column(Integer)  # 间隔秒数
    next_run = Column(DateTime)
    last_run = Column(DateTime)
    is_active = Column(Boolean, default=True)
    run_count = Column(Integer, default=0)


# ========================================================================
# 任务执行器
# ========================================================================

class TaskExecutor:
    """任务执行器"""
    
    def __init__(self, max_workers: int = 4):
        self.max_workers = max_workers
        self.executor = ThreadPoolExecutor(max_workers=max_workers)
        self.task_queue = queue.PriorityQueue()
        self.running_tasks: Dict[str, TaskResult] = {}
        self.completed_tasks: Dict[str, TaskResult] = {}
        self.logger = get_logger("TaskExecutor")
        self.cache = MemoryCache()
        
        # 初始化数据库
        self.db_session = DatabaseSession(
            database_url="sqlite:///background_tasks.db",
            echo=False
        )
        self.db_session.create_tables()
        
        # 启动任务处理线程
        self.running = True
        self.worker_thread = threading.Thread(target=self._process_tasks, daemon=True)
        self.worker_thread.start()
        
        # 注册任务函数
        self.task_functions = {}
        self._register_default_tasks()
    
    def _register_default_tasks(self):
        """注册默认任务函数"""
        self.register_task("send_email", self._send_email_task)
        self.register_task("process_data", self._process_data_task)
        self.register_task("generate_report", self._generate_report_task)
        self.register_task("backup_database", self._backup_database_task)
        self.register_task("cleanup_files", self._cleanup_files_task)
        self.register_task("sync_data", self._sync_data_task)
        self.register_task("calculate_metrics", self._calculate_metrics_task)
    
    def register_task(self, name: str, func):
        """注册任务函数"""
        self.task_functions[name] = func
        self.logger.info("Task function registered", name=name)
    
    def submit_task(self, name: str, function_name: str, args: List = None, 
                   kwargs: Dict = None, priority: TaskPriority = TaskPriority.NORMAL,
                   max_retries: int = 3, scheduled_at: datetime = None) -> str:
        """提交任务"""
        task_id = generate_uuid()
        
        # 保存任务到数据库
        session = self.db_session.get_session()
        
        try:
            task = Task(
                task_id=task_id,
                name=name,
                function_name=function_name,
                args=json.dumps(args or []),
                kwargs=json.dumps(kwargs or {}),
                priority=priority,
                max_retries=max_retries,
                scheduled_at=scheduled_at
            )
            
            session.add(task)
            session.commit()
            
            # 如果是立即执行的任务，加入队列
            if not scheduled_at or scheduled_at <= datetime.utcnow():
                priority_value = self._get_priority_value(priority)
                self.task_queue.put((priority_value, time.time(), task_id))
            
            self.logger.info(
                "Task submitted",
                task_id=task_id,
                name=name,
                function_name=function_name,
                priority=priority.value
            )
            
            return task_id
            
        finally:
            session.close()
    
    def _get_priority_value(self, priority: TaskPriority) -> int:
        """获取优先级数值（数值越小优先级越高）"""
        priority_map = {
            TaskPriority.URGENT: 1,
            TaskPriority.HIGH: 2,
            TaskPriority.NORMAL: 3,
            TaskPriority.LOW: 4
        }
        return priority_map.get(priority, 3)
    
    def _process_tasks(self):
        """处理任务队列"""
        while self.running:
            try:
                # 检查定时任务
                self._check_scheduled_tasks()
                
                # 处理队列中的任务
                try:
                    priority, timestamp, task_id = self.task_queue.get(timeout=1)
                    self._execute_task(task_id)
                except queue.Empty:
                    continue
                    
            except Exception as e:
                self.logger.error("Task processing error", error=str(e))
                time.sleep(1)
    
    def _check_scheduled_tasks(self):
        """检查定时任务"""
        session = self.db_session.get_session()
        
        try:
            now = datetime.utcnow()
            
            # 检查需要执行的定时任务
            scheduled_tasks = session.query(Task).filter(
                Task.status == TaskStatus.PENDING,
                Task.scheduled_at <= now,
                Task.scheduled_at.isnot(None)
            ).all()
            
            for task in scheduled_tasks:
                priority_value = self._get_priority_value(task.priority)
                self.task_queue.put((priority_value, time.time(), task.task_id))
                
                # 更新任务状态
                task.scheduled_at = None
                session.commit()
                
        finally:
            session.close()
    
    def _execute_task(self, task_id: str):
        """执行任务"""
        session = self.db_session.get_session()
        
        try:
            task = session.query(Task).filter(Task.task_id == task_id).first()
            if not task:
                return
            
            # 检查任务函数是否存在
            if task.function_name not in self.task_functions:
                self._update_task_status(
                    task_id, TaskStatus.FAILED, 
                    error=f"Task function '{task.function_name}' not found"
                )
                return
            
            # 更新任务状态为运行中
            task.status = TaskStatus.RUNNING
            task.started_at = datetime.utcnow()
            session.commit()
            
            # 创建任务结果对象
            task_result = TaskResult(
                task_id=task_id,
                status=TaskStatus.RUNNING,
                started_at=task.started_at
            )
            self.running_tasks[task_id] = task_result
            
            try:
                # 解析参数
                args = json.loads(task.args) if task.args else []
                kwargs = json.loads(task.kwargs) if task.kwargs else {}
                
                # 执行任务
                func = self.task_functions[task.function_name]
                result = func(*args, **kwargs)
                
                # 更新任务结果
                completed_at = datetime.utcnow()
                duration = (completed_at - task.started_at).total_seconds()
                
                task_result.status = TaskStatus.SUCCESS
                task_result.result = result
                task_result.completed_at = completed_at
                task_result.duration = duration
                
                # 更新数据库
                task.status = TaskStatus.SUCCESS
                task.result = json.dumps(result) if result else None
                task.completed_at = completed_at
                session.commit()
                
                self.logger.info(
                    "Task completed successfully",
                    task_id=task_id,
                    function_name=task.function_name,
                    duration=duration
                )
                
            except Exception as e:
                # 任务执行失败
                error_message = str(e)
                
                task_result.status = TaskStatus.FAILED
                task_result.error = error_message
                task_result.completed_at = datetime.utcnow()
                
                # 检查是否需要重试
                if task.retry_count < task.max_retries:
                    task.retry_count += 1
                    task.status = TaskStatus.RETRY
                    task.error_message = error_message
                    
                    # 重新加入队列（延迟重试）
                    retry_delay = min(2 ** task.retry_count, 60)  # 指数退避
                    threading.Timer(
                        retry_delay,
                        lambda: self.task_queue.put((
                            self._get_priority_value(task.priority),
                            time.time(),
                            task_id
                        ))
                    ).start()
                    
                    self.logger.warning(
                        "Task failed, will retry",
                        task_id=task_id,
                        retry_count=task.retry_count,
                        error=error_message
                    )
                else:
                    task.status = TaskStatus.FAILED
                    task.error_message = error_message
                    task.completed_at = datetime.utcnow()
                    
                    self.logger.error(
                        "Task failed permanently",
                        task_id=task_id,
                        error=error_message
                    )
                
                session.commit()
            
            # 移动到已完成任务
            self.completed_tasks[task_id] = task_result
            if task_id in self.running_tasks:
                del self.running_tasks[task_id]
                
        finally:
            session.close()
    
    def _update_task_status(self, task_id: str, status: TaskStatus, error: str = None):
        """更新任务状态"""
        session = self.db_session.get_session()
        
        try:
            task = session.query(Task).filter(Task.task_id == task_id).first()
            if task:
                task.status = status
                if error:
                    task.error_message = error
                if status in [TaskStatus.SUCCESS, TaskStatus.FAILED]:
                    task.completed_at = datetime.utcnow()
                session.commit()
                
        finally:
            session.close()
    
    def get_task_status(self, task_id: str) -> Optional[TaskResult]:
        """获取任务状态"""
        # 先检查运行中的任务
        if task_id in self.running_tasks:
            return self.running_tasks[task_id]
        
        # 检查已完成的任务
        if task_id in self.completed_tasks:
            return self.completed_tasks[task_id]
        
        # 从数据库查询
        session = self.db_session.get_session()
        
        try:
            task = session.query(Task).filter(Task.task_id == task_id).first()
            if not task:
                return None
            
            result = TaskResult(
                task_id=task.task_id,
                status=task.status,
                started_at=task.started_at,
                completed_at=task.completed_at
            )
            
            if task.result:
                result.result = json.loads(task.result)
            if task.error_message:
                result.error = task.error_message
            if task.started_at and task.completed_at:
                result.duration = (task.completed_at - task.started_at).total_seconds()
            
            return result
            
        finally:
            session.close()
    
    def cancel_task(self, task_id: str) -> bool:
        """取消任务"""
        session = self.db_session.get_session()
        
        try:
            task = session.query(Task).filter(Task.task_id == task_id).first()
            if not task:
                return False
            
            if task.status in [TaskStatus.PENDING, TaskStatus.RETRY]:
                task.status = TaskStatus.CANCELLED
                task.completed_at = datetime.utcnow()
                session.commit()
                
                self.logger.info("Task cancelled", task_id=task_id)
                return True
            
            return False
            
        finally:
            session.close()
    
    def get_task_list(self, status: TaskStatus = None, limit: int = 50) -> List[Dict]:
        """获取任务列表"""
        session = self.db_session.get_session()
        
        try:
            query = session.query(Task)
            
            if status:
                query = query.filter(Task.status == status)
            
            tasks = query.order_by(Task.created_at.desc()).limit(limit).all()
            
            result = []
            for task in tasks:
                data = {
                    "task_id": task.task_id,
                    "name": task.name,
                    "function_name": task.function_name,
                    "priority": task.priority.value,
                    "status": task.status.value,
                    "retry_count": task.retry_count,
                    "max_retries": task.max_retries,
                    "created_at": task.created_at.isoformat(),
                    "started_at": task.started_at.isoformat() if task.started_at else None,
                    "completed_at": task.completed_at.isoformat() if task.completed_at else None,
                    "scheduled_at": task.scheduled_at.isoformat() if task.scheduled_at else None
                }
                
                if task.result:
                    data["result"] = json.loads(task.result)
                if task.error_message:
                    data["error"] = task.error_message
                
                result.append(data)
            
            return result
            
        finally:
            session.close()
    
    # ========================================================================
    # 默认任务函数
    # ========================================================================
    
    def _send_email_task(self, to: str, subject: str, body: str, **kwargs):
        """发送邮件任务"""
        self.logger.info("Sending email", to=to, subject=subject)
        
        # 模拟邮件发送
        time.sleep(2)
        
        return {
            "status": "sent",
            "to": to,
            "subject": subject,
            "sent_at": datetime.utcnow().isoformat()
        }
    
    def _process_data_task(self, data_type: str, data_size: int = 1000, **kwargs):
        """数据处理任务"""
        self.logger.info("Processing data", data_type=data_type, data_size=data_size)
        
        # 模拟数据处理
        processed = 0
        for i in range(data_size):
            time.sleep(0.001)  # 模拟处理时间
            processed += 1
            
            # 每处理100条记录更新一次进度
            if processed % 100 == 0:
                progress = (processed / data_size) * 100
                self.logger.info("Processing progress", progress=f"{progress:.1f}%")
        
        return {
            "status": "completed",
            "data_type": data_type,
            "processed_count": processed,
            "completed_at": datetime.utcnow().isoformat()
        }
    
    def _generate_report_task(self, report_type: str, date_range: str = "last_7_days", **kwargs):
        """生成报告任务"""
        self.logger.info("Generating report", report_type=report_type, date_range=date_range)
        
        # 模拟报告生成
        time.sleep(5)
        
        report_data = {
            "type": report_type,
            "date_range": date_range,
            "total_records": 1500,
            "summary": {
                "success_rate": 95.5,
                "error_rate": 4.5,
                "average_response_time": 250
            },
            "generated_at": datetime.utcnow().isoformat()
        }
        
        return report_data
    
    def _backup_database_task(self, database_name: str, backup_type: str = "full", **kwargs):
        """数据库备份任务"""
        self.logger.info("Backing up database", database_name=database_name, backup_type=backup_type)
        
        # 模拟备份过程
        time.sleep(10)
        
        return {
            "status": "completed",
            "database_name": database_name,
            "backup_type": backup_type,
            "backup_size": "2.5GB",
            "backup_file": f"backup_{database_name}_{datetime.utcnow().strftime('%Y%m%d_%H%M%S')}.sql",
            "completed_at": datetime.utcnow().isoformat()
        }
    
    def _cleanup_files_task(self, directory: str, days_old: int = 30, **kwargs):
        """清理文件任务"""
        self.logger.info("Cleaning up files", directory=directory, days_old=days_old)
        
        # 模拟文件清理
        time.sleep(3)
        
        return {
            "status": "completed",
            "directory": directory,
            "days_old": days_old,
            "files_deleted": 45,
            "space_freed": "1.2GB",
            "completed_at": datetime.utcnow().isoformat()
        }
    
    def _sync_data_task(self, source: str, destination: str, **kwargs):
        """数据同步任务"""
        self.logger.info("Syncing data", source=source, destination=destination)
        
        # 模拟数据同步
        time.sleep(8)
        
        return {
            "status": "completed",
            "source": source,
            "destination": destination,
            "records_synced": 2500,
            "sync_duration": "8.2s",
            "completed_at": datetime.utcnow().isoformat()
        }
    
    def _calculate_metrics_task(self, metric_type: str, period: str = "daily", **kwargs):
        """计算指标任务"""
        self.logger.info("Calculating metrics", metric_type=metric_type, period=period)
        
        # 模拟指标计算
        time.sleep(4)
        
        return {
            "status": "completed",
            "metric_type": metric_type,
            "period": period,
            "metrics": {
                "total_users": 15420,
                "active_users": 8750,
                "conversion_rate": 12.5,
                "revenue": 45600.75
            },
            "calculated_at": datetime.utcnow().isoformat()
        }


# ========================================================================
# 定时任务调度器
# ========================================================================

class JobScheduler:
    """定时任务调度器"""
    
    def __init__(self, task_executor: TaskExecutor):
        self.task_executor = task_executor
        self.logger = get_logger("JobScheduler")
        self.running = True
        
        # 启动调度器线程
        self.scheduler_thread = threading.Thread(target=self._run_scheduler, daemon=True)
        self.scheduler_thread.start()
    
    def _run_scheduler(self):
        """运行调度器"""
        while self.running:
            try:
                schedule.run_pending()
                time.sleep(1)
            except Exception as e:
                self.logger.error("Scheduler error", error=str(e))
                time.sleep(5)
    
    def add_job(self, name: str, function_name: str, cron_expression: str = None,
               interval_seconds: int = None, args: List = None, kwargs: Dict = None) -> str:
        """添加定时任务"""
        job_id = generate_uuid()
        
        # 计算下次执行时间
        next_run = self._calculate_next_run(cron_expression, interval_seconds)
        
        # 保存到数据库
        session = self.task_executor.db_session.get_session()
        
        try:
            job = ScheduledJob(
                job_id=job_id,
                name=name,
                function_name=function_name,
                args=json.dumps(args or []),
                kwargs=json.dumps(kwargs or {}),
                cron_expression=cron_expression,
                interval_seconds=interval_seconds,
                next_run=next_run
            )
            
            session.add(job)
            session.commit()
            
            # 注册到schedule库
            if interval_seconds:
                schedule.every(interval_seconds).seconds.do(
                    self._execute_scheduled_job, job_id
                ).tag(job_id)
            
            self.logger.info(
                "Scheduled job added",
                job_id=job_id,
                name=name,
                next_run=next_run.isoformat() if next_run else None
            )
            
            return job_id
            
        finally:
            session.close()
    
    def _calculate_next_run(self, cron_expression: str = None, 
                          interval_seconds: int = None) -> Optional[datetime]:
        """计算下次执行时间"""
        if interval_seconds:
            return datetime.utcnow() + timedelta(seconds=interval_seconds)
        
        # 简化的cron解析（实际应用中应使用专门的cron库）
        if cron_expression:
            return datetime.utcnow() + timedelta(minutes=1)  # 简化处理
        
        return None
    
    def _execute_scheduled_job(self, job_id: str):
        """执行定时任务"""
        session = self.task_executor.db_session.get_session()
        
        try:
            job = session.query(ScheduledJob).filter(ScheduledJob.job_id == job_id).first()
            if not job or not job.is_active:
                return
            
            # 解析参数
            args = json.loads(job.args) if job.args else []
            kwargs = json.loads(job.kwargs) if job.kwargs else {}
            
            # 提交任务
            task_id = self.task_executor.submit_task(
                name=f"Scheduled: {job.name}",
                function_name=job.function_name,
                args=args,
                kwargs=kwargs,
                priority=TaskPriority.NORMAL
            )
            
            # 更新任务记录
            job.last_run = datetime.utcnow()
            job.run_count += 1
            job.next_run = self._calculate_next_run(job.cron_expression, job.interval_seconds)
            session.commit()
            
            self.logger.info(
                "Scheduled job executed",
                job_id=job_id,
                task_id=task_id,
                run_count=job.run_count
            )
            
        finally:
            session.close()
    
    def remove_job(self, job_id: str) -> bool:
        """移除定时任务"""
        session = self.task_executor.db_session.get_session()
        
        try:
            job = session.query(ScheduledJob).filter(ScheduledJob.job_id == job_id).first()
            if not job:
                return False
            
            # 从schedule库移除
            schedule.clear(job_id)
            
            # 从数据库删除
            session.delete(job)
            session.commit()
            
            self.logger.info("Scheduled job removed", job_id=job_id)
            return True
            
        finally:
            session.close()
    
    def get_jobs(self) -> List[Dict]:
        """获取定时任务列表"""
        session = self.task_executor.db_session.get_session()
        
        try:
            jobs = session.query(ScheduledJob).order_by(ScheduledJob.created_at.desc()).all()
            
            result = []
            for job in jobs:
                data = {
                    "job_id": job.job_id,
                    "name": job.name,
                    "function_name": job.function_name,
                    "cron_expression": job.cron_expression,
                    "interval_seconds": job.interval_seconds,
                    "is_active": job.is_active,
                    "run_count": job.run_count,
                    "created_at": job.created_at.isoformat(),
                    "next_run": job.next_run.isoformat() if job.next_run else None,
                    "last_run": job.last_run.isoformat() if job.last_run else None
                }
                result.append(data)
            
            return result
            
        finally:
            session.close()


# ========================================================================
# Flask应用
# ========================================================================

def create_task_queue_app() -> Flask:
    """创建任务队列应用"""
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'task-queue-demo-secret'
    
    # 初始化日志
    setup_logging()
    logger = get_logger("TaskQueueApp")
    
    # 初始化组件
    jwt_auth = JWTAuth(secret_key=app.config['SECRET_KEY'])
    task_executor = TaskExecutor(max_workers=4)
    job_scheduler = JobScheduler(task_executor)
    
    # 中间件
    @app.before_request
    def before_request():
        g.request_id = generate_uuid()
        g.start_time = time.time()
        
        logger.info(
            "Request started",
            request_id=g.request_id,
            method=request.method,
            path=request.path
        )
    
    @app.after_request
    def after_request(response):
        duration = time.time() - g.start_time
        
        logger.info(
            "Request completed",
            request_id=g.request_id,
            status_code=response.status_code,
            duration=duration
        )
        
        return response
    
    # 异常处理
    @app.errorhandler(ValidationError)
    def handle_validation_error(e):
        return jsonify(ErrorResponse.create(message=str(e)).dict()), 400
    
    @app.errorhandler(NotFoundError)
    def handle_not_found_error(e):
        return jsonify(ErrorResponse.create(message=str(e)).dict()), 404
    
    # ========================================================================
    # 任务管理API
    # ========================================================================
    
    @app.route('/tasks', methods=['POST'])
    def submit_task():
        """提交任务"""
        try:
            data = request.get_json()
            
            name = data.get('name')
            function_name = data.get('function_name')
            args = data.get('args', [])
            kwargs = data.get('kwargs', {})
            priority_str = data.get('priority', 'normal')
            max_retries = data.get('max_retries', 3)
            scheduled_at_str = data.get('scheduled_at')
            
            if not name or not function_name:
                raise ValidationError("name and function_name are required")
            
            try:
                priority = TaskPriority(priority_str)
            except ValueError:
                raise ValidationError("Invalid priority")
            
            scheduled_at = None
            if scheduled_at_str:
                try:
                    scheduled_at = datetime.fromisoformat(scheduled_at_str.replace('Z', '+00:00'))
                except ValueError:
                    raise ValidationError("Invalid scheduled_at format")
            
            task_id = task_executor.submit_task(
                name=name,
                function_name=function_name,
                args=args,
                kwargs=kwargs,
                priority=priority,
                max_retries=max_retries,
                scheduled_at=scheduled_at
            )
            
            response = CreatedResponse.create(
                data={"task_id": task_id},
                message="Task submitted successfully"
            )
            return jsonify(response.dict()), 201
            
        except ValidationError as e:
            raise
        except Exception as e:
            logger.error("Submit task error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to submit task"
            ).dict()), 500
    
    @app.route('/tasks/<task_id>', methods=['GET'])
    def get_task_status(task_id: str):
        """获取任务状态"""
        try:
            task_result = task_executor.get_task_status(task_id)
            if not task_result:
                raise NotFoundError("Task not found")
            
            response = SuccessResponse.create(
                data={"task": task_result.to_dict()},
                message="Task status retrieved successfully"
            )
            return jsonify(response.dict())
            
        except NotFoundError as e:
            raise
        except Exception as e:
            logger.error("Get task status error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to get task status"
            ).dict()), 500
    
    @app.route('/tasks/<task_id>', methods=['DELETE'])
    def cancel_task(task_id: str):
        """取消任务"""
        try:
            success = task_executor.cancel_task(task_id)
            if not success:
                raise NotFoundError("Task not found or cannot be cancelled")
            
            response = SuccessResponse.create(
                message="Task cancelled successfully"
            )
            return jsonify(response.dict())
            
        except NotFoundError as e:
            raise
        except Exception as e:
            logger.error("Cancel task error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to cancel task"
            ).dict()), 500
    
    @app.route('/tasks', methods=['GET'])
    def get_task_list():
        """获取任务列表"""
        try:
            status_str = request.args.get('status')
            limit = min(int(request.args.get('limit', 50)), 100)
            
            status = None
            if status_str:
                try:
                    status = TaskStatus(status_str)
                except ValueError:
                    raise ValidationError("Invalid status")
            
            tasks = task_executor.get_task_list(status=status, limit=limit)
            
            response = SuccessResponse.create(
                data={
                    "tasks": tasks,
                    "count": len(tasks),
                    "status_filter": status.value if status else None
                },
                message="Task list retrieved successfully"
            )
            return jsonify(response.dict())
            
        except ValidationError as e:
            raise
        except Exception as e:
            logger.error("Get task list error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to get task list"
            ).dict()), 500
    
    # ========================================================================
    # 定时任务API
    # ========================================================================
    
    @app.route('/jobs', methods=['POST'])
    def add_scheduled_job():
        """添加定时任务"""
        try:
            data = request.get_json()
            
            name = data.get('name')
            function_name = data.get('function_name')
            args = data.get('args', [])
            kwargs = data.get('kwargs', {})
            cron_expression = data.get('cron_expression')
            interval_seconds = data.get('interval_seconds')
            
            if not name or not function_name:
                raise ValidationError("name and function_name are required")
            
            if not cron_expression and not interval_seconds:
                raise ValidationError("Either cron_expression or interval_seconds is required")
            
            job_id = job_scheduler.add_job(
                name=name,
                function_name=function_name,
                cron_expression=cron_expression,
                interval_seconds=interval_seconds,
                args=args,
                kwargs=kwargs
            )
            
            response = CreatedResponse.create(
                data={"job_id": job_id},
                message="Scheduled job added successfully"
            )
            return jsonify(response.dict()), 201
            
        except ValidationError as e:
            raise
        except Exception as e:
            logger.error("Add scheduled job error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to add scheduled job"
            ).dict()), 500
    
    @app.route('/jobs/<job_id>', methods=['DELETE'])
    def remove_scheduled_job(job_id: str):
        """移除定时任务"""
        try:
            success = job_scheduler.remove_job(job_id)
            if not success:
                raise NotFoundError("Scheduled job not found")
            
            response = SuccessResponse.create(
                message="Scheduled job removed successfully"
            )
            return jsonify(response.dict())
            
        except NotFoundError as e:
            raise
        except Exception as e:
            logger.error("Remove scheduled job error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to remove scheduled job"
            ).dict()), 500
    
    @app.route('/jobs', methods=['GET'])
    def get_scheduled_jobs():
        """获取定时任务列表"""
        try:
            jobs = job_scheduler.get_jobs()
            
            response = SuccessResponse.create(
                data={
                    "jobs": jobs,
                    "count": len(jobs)
                },
                message="Scheduled jobs retrieved successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            logger.error("Get scheduled jobs error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to get scheduled jobs"
            ).dict()), 500
    
    # ========================================================================
    # 快捷任务API
    # ========================================================================
    
    @app.route('/tasks/email', methods=['POST'])
    def send_email_task():
        """发送邮件任务"""
        try:
            data = request.get_json()
            
            task_id = task_executor.submit_task(
                name="Send Email",
                function_name="send_email",
                args=[data.get('to'), data.get('subject'), data.get('body')],
                kwargs=data.get('kwargs', {}),
                priority=TaskPriority.HIGH
            )
            
            response = CreatedResponse.create(
                data={"task_id": task_id},
                message="Email task submitted successfully"
            )
            return jsonify(response.dict()), 201
            
        except Exception as e:
            logger.error("Send email task error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to submit email task"
            ).dict()), 500
    
    @app.route('/tasks/report', methods=['POST'])
    def generate_report_task():
        """生成报告任务"""
        try:
            data = request.get_json()
            
            task_id = task_executor.submit_task(
                name="Generate Report",
                function_name="generate_report",
                args=[data.get('report_type', 'daily')],
                kwargs={"date_range": data.get('date_range', 'last_7_days')},
                priority=TaskPriority.NORMAL
            )
            
            response = CreatedResponse.create(
                data={"task_id": task_id},
                message="Report generation task submitted successfully"
            )
            return jsonify(response.dict()), 201
            
        except Exception as e:
            logger.error("Generate report task error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to submit report generation task"
            ).dict()), 500
    
    @app.route('/tasks/backup', methods=['POST'])
    def backup_database_task():
        """数据库备份任务"""
        try:
            data = request.get_json()
            
            task_id = task_executor.submit_task(
                name="Database Backup",
                function_name="backup_database",
                args=[data.get('database_name', 'main')],
                kwargs={"backup_type": data.get('backup_type', 'full')},
                priority=TaskPriority.LOW
            )
            
            response = CreatedResponse.create(
                data={"task_id": task_id},
                message="Database backup task submitted successfully"
            )
            return jsonify(response.dict()), 201
            
        except Exception as e:
            logger.error("Database backup task error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to submit database backup task"
            ).dict()), 500
    
    # ========================================================================
    # 监控和统计API
    # ========================================================================
    
    @app.route('/stats', methods=['GET'])
    def get_task_stats():
        """获取任务统计"""
        try:
            # 获取各状态的任务数量
            stats = {}
            for status in TaskStatus:
                tasks = task_executor.get_task_list(status=status, limit=1000)
                stats[status.value] = len(tasks)
            
            # 运行中的任务
            running_tasks = len(task_executor.running_tasks)
            
            # 队列中的任务
            queue_size = task_executor.task_queue.qsize()
            
            response = SuccessResponse.create(
                data={
                    "task_stats": stats,
                    "running_tasks": running_tasks,
                    "queue_size": queue_size,
                    "worker_count": task_executor.max_workers,
                    "timestamp": datetime.utcnow().isoformat()
                },
                message="Task statistics retrieved successfully"
            )
            return jsonify(response.dict())
            
        except Exception as e:
            logger.error("Get task stats error", error=str(e))
            return jsonify(ErrorResponse.create(
                message="Failed to get task statistics"
            ).dict()), 500
    
    @app.route('/health', methods=['GET'])
    def health_check():
        """健康检查"""
        return jsonify({
            "status": "healthy",
            "timestamp": datetime.utcnow().isoformat(),
            "task_executor": {
                "running": task_executor.running,
                "max_workers": task_executor.max_workers,
                "running_tasks": len(task_executor.running_tasks),
                "queue_size": task_executor.task_queue.qsize()
            },
            "job_scheduler": {
                "running": job_scheduler.running
            }
        })
    
    @app.route('/info', methods=['GET'])
    def app_info():
        """应用信息"""
        return jsonify({
            "name": "Task Queue and Background Jobs Demo",
            "version": "1.0.0",
            "description": "任务队列和后台作业示例 - 异步任务处理、定时任务等功能",
            "features": [
                "异步任务处理",
                "任务优先级",
                "任务重试机制",
                "定时任务调度",
                "任务状态监控",
                "任务取消",
                "任务统计",
                "多线程执行"
            ],
            "task_functions": list(task_executor.task_functions.keys()),
            "endpoints": {
                "tasks": [
                    "POST /tasks - 提交任务",
                    "GET  /tasks - 获取任务列表",
                    "GET  /tasks/<id> - 获取任务状态",
                    "DELETE /tasks/<id> - 取消任务"
                ],
                "scheduled_jobs": [
                    "POST /jobs - 添加定时任务",
                    "GET  /jobs - 获取定时任务列表",
                    "DELETE /jobs/<id> - 移除定时任务"
                ],
                "quick_tasks": [
                    "POST /tasks/email - 发送邮件任务",
                    "POST /tasks/report - 生成报告任务",
                    "POST /tasks/backup - 数据库备份任务"
                ],
                "monitoring": [
                    "GET /stats - 获取任务统计",
                    "GET /health - 健康检查"
                ]
            }
        })
    
    return app


if __name__ == '__main__':
    app = create_task_queue_app()
    
    print("=" * 60)
    print("Flask Task Queue and Background Jobs Demo")
    print("=" * 60)
    print("任务队列和后台作业演示:")
    print("  功能特性:")
    print("    - 异步任务处理")
    print("    - 任务优先级管理")
    print("    - 任务重试机制")
    print("    - 定时任务调度")
    print("    - 任务状态监控")
    print("    - 任务取消功能")
    print("    - 多线程执行")
    print("    - 任务统计分析")
    print()
    print("  内置任务函数:")
    print("    - send_email - 发送邮件")
    print("    - process_data - 数据处理")
    print("    - generate_report - 生成报告")
    print("    - backup_database - 数据库备份")
    print("    - cleanup_files - 文件清理")
    print("    - sync_data - 数据同步")
    print("    - calculate_metrics - 计算指标")
    print()
    print("  API端点:")
    print("    任务管理:")
    print("      POST /tasks - 提交任务")
    print("      GET  /tasks - 获取任务列表")
    print("      GET  /tasks/<id> - 获取任务状态")
    print("      DELETE /tasks/<id> - 取消任务")
    print("    定时任务:")
    print("      POST /jobs - 添加定时任务")
    print("      GET  /jobs - 获取定时任务列表")
    print("      DELETE /jobs/<id> - 移除定时任务")
    print("    快捷任务:")
    print("      POST /tasks/email - 发送邮件任务")
    print("      POST /tasks/report - 生成报告任务")
    print("      POST /tasks/backup - 数据库备份任务")
    print("    监控:")
    print("      GET /stats - 获取任务统计")
    print("      GET /health - 健康检查")
    print("=" * 60)
    
    app.run(
        host='0.0.0.0',
        port=5014,
        debug=True
    )